package com.rao.crm.dao.impl;

import com.rao.crm.dao.BaseDao;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

/**
 * @author Srao
 * @version 1.0
 * @className BaseDaoImpl
 * @date 2019/9/21 14:32
 * @package com.rao.crm.dao.impl
 * @description
 */
public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {

    private Class clazz;

    public BaseDaoImpl(){
        Class<? extends BaseDaoImpl> clazz = this.getClass();//哪个类在被调用，返回的就是谁的Class，如Customer.class获得LinkMan.class
        Type CommonType = clazz.getGenericSuperclass();//返回的是普通的类型，如BaseDaoImpl<Customer>，BaseDaoImpl<LinkMan>
        ParameterizedType parameterizedType = (ParameterizedType)CommonType;//把普通类型转化为参数化类型
        Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();//获得实际参数数组，因为有Map<String, String>类型，所以得到的是一个数组
        this.clazz = (Class) actualTypeArguments[0];//把数组里的第一个值赋给clazz
    }

    @Override
    public void save(T t) {
        this.getHibernateTemplate().save(t);
    }

    @Override
    public void delete(T t) {
        this.getHibernateTemplate().delete(t);
    }

    @Override
    public void update(T t) {
        this.getHibernateTemplate().update(t);
    }

    @Override
    public T findById(Serializable id) {
        return (T) this.getHibernateTemplate().get(clazz, id);
    }

    @Override
    public Integer findTotalCount(DetachedCriteria detachedCriteria) {
        detachedCriteria.setProjection(Projections.rowCount());
        List<Long> list = (List<Long>) this.getHibernateTemplate().findByCriteria(detachedCriteria);
        if (list.size() > 0){
            return list.get(0).intValue();
        }
        return null;
    }

    @Override
    public List<T> findAll() {
        return (List<T>) this.getHibernateTemplate().find("from " + clazz.getSimpleName());
    }

    @Override
    public List<T> findAll(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize) {
        detachedCriteria.setProjection(null);
        return (List<T>) this.getHibernateTemplate().findByCriteria(detachedCriteria, startIndex, pageSize);
    }
}
